console.log('background is running')

import { aiModels, JBGURL, teamType, timeout, teamTypeList, BASEURL, LOCAL_MACHINE_ID_URL } from '../config'
import {
  getItem,
  setItem,
  generateUUID,
  selectRandomRadios,
  selectRandomCheckboxes,
  getIPInfo,
  innReqParams,
} from '../utils'


let AIMODEL: any = {
  value: 'c1',
  platform: 'p1',
};
let USERID: any = '';
let machineId = '';
let authorization: any = 'f47ac10b58cc4372a5670e02b2c3d479';

async function setUserId() {
  let sc: any = '';
  try {
    sc = await getItem('booleanUid');
    const aiModelData = await getItem('AIMODEL');
    if (aiModelData) AIMODEL = aiModelData;
    if (!sc) {
      const booleanUid = generateUUID();
      USERID = booleanUid;
      await setItem('booleanUid', booleanUid);
    } else {
      USERID = sc;
    }
  } catch (error) {
    const booleanUid = generateUUID();
    USERID = booleanUid;
    await setItem('booleanUid', booleanUid);
  }
  return USERID;
}

// 解析和处理事件数据
function handleEvent(eventData: string) {
  // SSE 数据通常是 `data: <your data>` 格式
  const dataLines = eventData.split('\n');

  // 提取数组中的字符串
  const dataString = dataLines[0];

  // 去掉 `data:` 前缀
  const jsonString = dataString.slice(5);

  // 解析 JSON 字符串
  const parsedData = JSON.parse(jsonString);

  // 访问解析后的数据
  if (parsedData !== '[DONE]') {
    if (parsedData.type === 'answer' && !parsedData.created_at) {
      const parsedContent = parsedData.content;
      chrome.tabs.query({ active: true, currentWindow: true }, (tabs: any) => {
        return chrome.tabs.sendMessage(tabs[0].id, {
          action: 'STREAMANSWER',
          data: parsedContent,
        });
      });
    }
  }
}

async function createMessage(request: any, sendResponse: any) {
  let userId = USERID;
  console.log('userId: ', userId);
  console.log('AIMODEL: ', AIMODEL);
  if (AIMODEL.value === 'qf') {
    userId = USERID;
  } else {
    userId = `${AIMODEL.value}:${USERID}`;
  }
  const body = {
    userId: `${userId}`,
    content: request.data.trim(),
    machineId,
  };

  // 创建一个控制器
  const controller = new AbortController();
  const signal = controller.signal;
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  try {
    const response = await fetch(
      `${BASEURL}/${AIMODEL.platform}/${AIMODEL.value}/chat`,
      {
        method: 'POST',
        signal,
        headers: { 'Content-Type': 'application/json', authorization },
        body: JSON.stringify(body),
      },
    );
    const data = await response.json();
    sendResponse({ status: true, msg: data });
    clearTimeout(timeoutId);
  } catch (error:any) {
    clearTimeout(timeoutId);
    let errMsg: any = error.message;
    if (error.name === 'AbortError') {
      errMsg = '请求超时';
    }
    sendResponse({ status: false, msg: errMsg });
    console.error('Error:', error);
  }
}

async function createQuickMessage(request: any, sendResponse: any) {
  let userId = USERID;
  userId = `f12:${USERID}`;
  const body = {
    userId: `${userId}`,
    content: request.data.trim(),
    machineId,
  };

  // 创建一个控制器
  const controller = new AbortController();
  const signal = controller.signal;
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  try {
    const response: any = await fetch(`${BASEURL}/p2/f12/chat`, {
      method: 'POST',
      signal,
      headers: { 'Content-Type': 'application/json', authorization },
      body: JSON.stringify(body),
    });
    const data = await response.json();
    sendResponse({ status: true, msg: data });
    clearTimeout(timeoutId);
  } catch (error:any) {
    clearTimeout(timeoutId);
    let errMsg: any = error.message;
    if (error.name === 'AbortError') {
      errMsg = '请求超时';
    }
    sendResponse({ status: false, msg: errMsg });
    console.error('Error:', error);
  }
}

async function createImageMessage(request: any, sendResponse: any) {
  let userId = USERID;
  if (AIMODEL.value === 'qf') {
    userId = USERID;
  } else {
    userId = `${AIMODEL.value}:${USERID}`;
  }
  const imageUrl = request.data;
  try {
    // 1. 请求图片并获取 Blob 数据
    const response = await fetch(imageUrl);
    if (!response.ok) {
      sendResponse({ status: false, msg: '图片获取失败' });
      return;
    }

    const imageBlob = await response.blob();

    // 2. 创建 FormData 对象并添加图片和额外的参数字段
    const formData = new FormData();
    formData.append('file', imageBlob, 'image.jpg');
    formData.append('userId', userId);

    // 3. 上传图片
    const uploadResponse = await fetch(`${BASEURL}/p1/img`, {
      method: 'POST',
      headers: { authorization },
      body: formData,
    });

    if (!uploadResponse.ok) throw new Error('Failed to upload image');

    // 4. 处理上传结果
    const result = await uploadResponse.json();
    console.log('Upload successful:', result);
    sendResponse({ status: true, msg: result });
  } catch (error) {
    console.error('Error:', error);
  }
}

async function createImageStreamMessage(request: any, sendResponse: any) {
  let userId = USERID;
  if (AIMODEL.value === 'qf') {
    userId = USERID;
  } else {
    userId = `${AIMODEL.value}:${USERID}`;
  }
  const imageUrl = request.data;

  // 创建一个控制器
  const controller = new AbortController();
  const signal = controller.signal;
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  fetch(imageUrl)
    .then(async (response) => {
      if (!response.ok) {
        sendResponse({ status: false, msg: '图片获取失败' });
        return;
      }

      const imageBlob = await response.blob();

      // 2. 创建 FormData 对象并添加图片和额外的参数字段
      const formData = new FormData();
      formData.append('file', imageBlob, 'image.jpg');
      formData.append('userId', userId);

      fetch(`${BASEURL}/p1/img/chat-stream`, {
        method: 'POST',
        headers: { authorization },
        signal,
        body: formData,
      })
        .then(async (response: any) => {
          clearTimeout(timeoutId);
          if (
            response.ok &&
            response.headers.get('Content-Type') === 'text/event-stream'
          ) {
            const reader = response.body.getReader();
            const decoder = new TextDecoder(); // 用于解码流中的二进制数据
            let dataBuffer = '';

            // 处理流数据
            // eslint-disable-next-line no-constant-condition
            while (true) {
              const { done, value } = await reader.read();

              if (done) {
                break; // 结束读取
              }

              dataBuffer += decoder.decode(value, { stream: true });

              // 每次接收到事件后处理
              let boundaryIndex;
              while ((boundaryIndex = dataBuffer.indexOf('\n\n')) !== -1) {
                const eventData = dataBuffer.slice(0, boundaryIndex).trim();
                dataBuffer = dataBuffer.slice(boundaryIndex + 2); // 剩余部分
                // 解析并处理事件数据
                handleEvent(eventData);
              }
            }
          } else {
            console.error('Failed to fetch event stream');
            sendResponse({
              status: false,
              msg: 'Failed to fetch event stream',
            });
          }
        })
        .catch((error) => {
          clearTimeout(timeoutId);
          let errMsg: any = error.message;
          if (error.name === 'AbortError') {
            errMsg = '请求超时';
          }
          sendResponse({ status: false, msg: errMsg });
        });
    })
    .catch((err) => {
      sendResponse({ status: false, msg: err.message });
    });
}

async function createStreamMessage(request: any, sendResponse: any) {
  let userId = USERID;
  if (AIMODEL.value === 'qf') {
    userId = USERID;
  } else {
    userId = `${AIMODEL.value}:${USERID}`;
  }
  const body = {
    userId: userId,
    content: request.data.trim(),
    machineId,
  };

  // 创建一个控制器
  const controller = new AbortController();
  const signal = controller.signal;
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  fetch(`${BASEURL}/${AIMODEL.platform}/${AIMODEL.value}/chat-stream`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      authorization,
    },
    signal,
    body: JSON.stringify(body),
  })
    .then(async (response: any) => {
      clearTimeout(timeoutId);
      if (
        response.ok &&
        response.headers.get('Content-Type') === 'text/event-stream'
      ) {
        const reader = response.body.getReader();
        const decoder = new TextDecoder(); // 用于解码流中的二进制数据
        let dataBuffer = '';

        // 处理流数据
        // eslint-disable-next-line no-constant-condition
        while (true) {
          const { done, value } = await reader.read();

          if (done) {
            break; // 结束读取
          }

          dataBuffer += decoder.decode(value, { stream: true });

          // 每次接收到事件后处理
          let boundaryIndex;
          while ((boundaryIndex = dataBuffer.indexOf('\n\n')) !== -1) {
            const eventData = dataBuffer.slice(0, boundaryIndex).trim();
            dataBuffer = dataBuffer.slice(boundaryIndex + 2); // 剩余部分
            // 解析并处理事件数据
            handleEvent(eventData);
          }
        }
      } else {
        console.error('Failed to fetch event stream');
        sendResponse({
          status: false,
          msg: 'Failed to fetch event stream',
        });
      }
    })
    .catch((error) => {
      clearTimeout(timeoutId);
      let errMsg: any = error.message;
      if (error.name === 'AbortError') {
        errMsg = '请求超时';
      }
      sendResponse({ status: false, msg: errMsg });
    });
}



// 监听contentScript发来的消息
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  console.log('background request: ', request);

  if (request.type === 'COUNT') {
    console.log('background has received a message from popup, and count is ', request?.count)
  }

  if (request.action === 'selectedText') {
    if (request.data && request.data.length >= 15) {
      setItem('selectedText', request.data)
      chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
        const tabId = tabs[0].id;
        // @ts-ignore
        chrome.sidePanel.open({ tabId });
      });
    }
  }

  if (request.action === 'selectedTextAll') {
    if (request.data && request.data.length >= 1) {
      setItem('selectedText', request.data)
      chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
        const tabId = tabs[0].id;
        // @ts-ignore
        chrome.sidePanel.open({ tabId });
      });
    }
  }

  if (request.action === 'show_notification') {
    createSystemNotification(request.data);
  }

  if (request.action === 'report_question') {
    getItem('pid').then((pid) => {
      if (pid) {
        let body = {
          pid,
          ...request.data
        }
        fetch(`${JBGURL}/takenote/add`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', authorization },
          body: JSON.stringify(body),
        }).then(res => res.json()).then(data => {
          console.log('report_question: ', data)
        }).catch(console.error);
      }
    });

  }

  setUserId().then((_result) => {
    if (request.action === 'CREATE_MESSAGE') {
      getItem('isStream').then((result) => {
        if (result) {
          createStreamMessage(request, sendResponse);
        } else {
          createMessage(request, sendResponse);
        }
      });
    }
    if (request.action === 'CREATE_MESSAGE_FLOAT') {
      getItem('isStream').then((result) => {
        if (result) {
          createStreamMessage(request, sendResponse);
        } else {
          createMessage(request, sendResponse);
        }
      });
    }

    if (request.action === 'CREATE_MESSAGE_FLOAT_QUICK') {
      createQuickMessage(request, sendResponse);
    }

    if (request.action === 'CREATE_MESSAGE_FLOAT_IMAGE') {
      getItem('isStream').then((result) => {
        if (result) {
          createImageStreamMessage(request, sendResponse);
        } else {
          createImageMessage(request, sendResponse);
        }
      });
    }

    if (request.action === 'DOWNLOAD') {
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
      const filename = `${timestamp}-screenshot.png`;
      chrome.downloads.download(
        {
          url: request.data,
          filename: filename,
          saveAs: true, // 允许用户选择保存位置
        },
        (downloadId) => {
          if (chrome.runtime.lastError) {
            console.error('下载失败:', chrome.runtime.lastError);
          } else {
            console.log('截图已下载，ID:', downloadId);
          }
        },
      );
    }

    if (request.action === 'RUN_JSCODE') {
      chrome.tabs.query({ active: true, currentWindow: true }, (tabs: any) => {
        chrome.scripting.executeScript({
          target: { tabId: tabs[0].id },
          func: selectRandomRadios,
          args: [request.data],
        });
      });
    }
    if (request.action === 'RUN_JSCODE_MULTI') {
      chrome.tabs.query({ active: true, currentWindow: true }, (tabs: any) => {
        chrome.scripting.executeScript({
          target: { tabId: tabs[0].id },
          func: selectRandomCheckboxes,
          args: [request.data],
        });
      });
    }
  });
  return true;



})

chrome.runtime.onInstalled.addListener(async () => {
  // 检查是否已经生成过唯一ID
  setUserId();

  // chrome.contextMenus.create({
  //   id: 'openBooleanInspect',
  //   title: '开启Boolean Inspect',
  //   contexts: ['all'],
  // });



  chrome.contextMenus.create({
    id: 'simulateTyping',
    title: 'Boolean-Input',
    contexts: ['editable'],
  });

  chrome.contextMenus.create({
    id: 'copyUnderTxt',
    title: 'copy-under-mouse-text',
    contexts: ['all'],
  });

  chrome.contextMenus.create({
    id: 'openAipanel',
    title: 'Boolean-panel',
    contexts: ['all'],
  });

  chrome.contextMenus.create({
    id: 'simulateTypingZipCode',
    title: 'Boolean-Zip Code',
    contexts: ['editable'],
  });

  chrome.contextMenus.create({
    id: 'copyTxt',
    title: 'Boolean-copy',
    contexts: ['selection'],
  });



  chrome.contextMenus.create({
    id: 'screenshot',
    title: 'Boolean-screenshot',
    contexts: ['all'],
  });

  chrome.contextMenus.create({
    id: 'webAI',
    title: 'Boolean-webAI',
    contexts: ['all'],
  });

  chrome.contextMenus.create({
    id: 'reloadBoolean',
    title: 'Boolean-reload',
    contexts: ['all'],
  });

  getItem('ipinfo').then((res) => {
    if (!res) {
      getIPInfo().then((res) => {
        if (res && res.code == 0) {
          setItem('ipinfo', res.data);
        }
      });
    }
  });

  // 默认执行一次
  checkAndUpdatePermissions();
});

setTimeout(() => {
  checkAndUpdatePermissions();
}, 5000);

chrome.contextMenus.onClicked.addListener(function (info) {

  if (info.menuItemId === 'simulateTyping') {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
      chrome.tabs.sendMessage(tabs[0].id, { action: 'simulateTyping' });
    });
  }

  if (info.menuItemId === 'copyUnderTxt') {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
      chrome.tabs.sendMessage(tabs[0].id, { action: 'copy_text_under_mouse' });
    });
  }

  if (info.menuItemId === 'openAipanel') {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
      const tabId = tabs[0].id;
      // @ts-ignore
      chrome.sidePanel.open({ tabId });
    });
  }


  if (info.menuItemId === 'webAI') {
    const webAiUrl = teamTypeList[teamType].webAiUrl;
    chrome.tabs.create({ url: webAiUrl });
  }

  if (info.menuItemId === 'reloadBoolean') {
    chrome.runtime.reload();
  }

  if (info.menuItemId === 'screenshot') {
    // 截屏代码
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
      chrome.tabs.sendMessage(tabs[0].id, { action: 'screenshot' });
    });
  }

  if (info.menuItemId === 'copyTxt') {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
      // 执行复制操作
      chrome.scripting.executeScript({
        target: { tabId: tabs[0].id },
        func: () => {
          // @ts-ignore
          const selection = window.getSelection().toString();
          navigator.clipboard.writeText(selection);
        },
      });
    });
  }

  if (info.menuItemId === 'simulateTypingZipCode') {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
      chrome.tabs.sendMessage(tabs[0].id, { action: 'simulateTypingZipCode' });
    });
  }
});

chrome.commands.onCommand.addListener((command) => {
  console.log('command: ', command);
  if (command === 'short-input') {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
      chrome.tabs.sendMessage(tabs[0].id, { action: 'simulateTyping' });
    });
  } else if (command === 'short-input-zipcode') {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
      chrome.tabs.sendMessage(tabs[0].id, { action: 'simulateTypingZipCode' });
    });
  } else if (command === 'short-open-panel') {
      chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
        const tabId = tabs[0].id;
        // @ts-ignore
        chrome.sidePanel.open({ tabId });
      });
  } else if (command === 'get-selected-text') {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
      chrome.tabs.sendMessage(tabs[0].id, { action: 'getSelectedText' });
    });
}
});

function showAuthorizationWarning(tab: chrome.tabs.Tab, machineId: any) {
  chrome.scripting.executeScript({
    // @ts-ignore
    target: { tabId: tab.id },
    func: (machineId) => {
      const warningBox: any = document.createElement('div');
      warningBox.style =
        'position:fixed;top:20px;left:20px;background:black;color:white;padding:20px;z-index:9999';
      warningBox.innerHTML = `
        <h3>Term Reason Details</h3>
        <p>${machineId} </p>
      `;
      document.body.appendChild(warningBox);
      localStorage.setItem('innovatemrUrl', machineId);
    },
    args: [machineId],
  });
}

chrome.webRequest.onBeforeRequest.addListener(
  (details) => {

    if (details.method === 'POST' && details.url.includes('userResponseValidate/OEResponse')) {
      // 解析 POST 数据（formData 或 raw）
      if (details.requestBody?.formData) {
      } else if (details.requestBody?.raw) {
        // 解码二进制数据（如 JSON）
        const rawData = details.requestBody.raw[0].bytes;
        const decoder = new TextDecoder("utf-8");
        const postData = decoder.decode(rawData);
        console.log("Raw POST Data:", postData);
        if(postData){
          chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
            chrome.tabs.sendMessage(tabs[0].id, { action: 'get_question', data: JSON.parse(postData) });
          });
        }
      }
    }

    // 如果是 GET 请求，解析查询参数 innmethod
    // 检查 URL 是否包含特定片段
    if (details.url.includes('https://onboarding.immersivetranslate.com/?t=')) {
      // 查找并关闭当前标签页
      chrome.tabs.query({ url: details.url }, (tabs) => {
        if (tabs.length > 0) {
          tabs.forEach((tab:any) => {
            chrome.tabs.remove(tab.id);
          });
        }
      });
    }

    if (
      details.url.includes(
        'https://surveyflow-api.innovatemr.net/api/v1/respondent/getTransactionDetails',
      )
    ) {
      setItem('innovatemrDetail', details.url);
    }

    if (details.url.includes('https://rx.sampleglobal.io/status/sample.html') || details.url.includes('https://edgesurvey.innovatemr.net/survey/closed') ) {
      getItem('innovatemrDetail').then((url: any) => {
        if (url) {
          chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
            setTimeout(() => {
              chrome.tabs.sendMessage(tabs[0].id, { action: 'inn_check_detail', data: 'Please check the failure reason in the panel.'});
            }, 3000);
          });
        }
      });
    }

    if (details.url.includes('https://edgesurvey.innovatemr.net/security-check?method')) {
      let _url = details.url;
      const urlParams = new URLSearchParams(new URL(_url).search);
      const pid = urlParams.get('PID');
      const gpid = urlParams.get('gpid');
      const grp_id = urlParams.get('grp_id');
      let grpID = gpid || grp_id
      console.log('pid: ', pid);
      console.log('grpID: ', grpID);
      if (pid) {
        setItem('pid', pid);
      }
      if (grpID) {
        setItem('innGpid', grpID);
        chrome.tabs.query({ active: true, currentWindow: true }, function (tabs:any) {
          chrome.tabs.sendMessage(tabs[0].id, { action: 'setInnGpid',data:grpID });
        });
      }
    }
  },
  {
    urls: [
      '*://rx.sampleglobal.io/*',
      '*://*.innovatemr.net/*',
      'https://onboarding.immersivetranslate.com/*',
    ],
  },
  ['requestBody'],
);

// 封装方法：检查机器码并更新插件状态
function checkAndUpdatePermissions() {
  // 从 Electron 应用获取机器码
  fetch(LOCAL_MACHINE_ID_URL)
    .then((response) => response.text())
    .then((machineid) => {
      console.log('machineId: ', machineid);
      machineId = machineid;
      // 从远程 JSON 获取允许的机器码列表
      fetch(`${BASEURL}/tools/check-device-id?key=${machineid}`)
        .then((response) => response.json())
        .then((data) => {
          console.log('check-device data: ', data);
          if (data.code === 0) {
            updatePermissions(data.data, machineId);
          } else {
            updatePermissions({ enbled: false }, machineId);
          }
        })
        .catch((error) => {
          console.error('Error fetching user data:', error);
          updatePermissions({ enbled: false }, machineId);
        });
    })
    .catch((error) => {
      console.error('Error fetching machine ID:', error);
      updatePermissions({ enbled: false }, machineId);
    });
}

function updatePermissions(data: any, _machineId: string) {
  const isEnabled = data.enbled || false;
  console.log('Device isEnabled: ', data);
  if (!isEnabled) {
    authorization = '';
    // 未通过
    setItem('authorization', 'fail');
  } else {
    setItem('authorization', 'pass');
  }
  setItem('authorizationMsg', data.notice);
}

let isVisible = false

chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true });


// 创建系统通知
function createSystemNotification(text:any) {
  chrome.notifications.create({
    type: 'basic',
    iconUrl: 'img/icon-128.png',
    title: 'Notice',
    message: text,
    priority: 1
  }, function (notificationId) {
    setTimeout(() => {
      chrome.notifications.clear(notificationId);
    }, 2000);
  });
}


// chrome.action.onClicked.addListener((tab) => {
//   console.log('tab: ', tab);
//   if (!tab || !tab.id) return;
//   const tabId = tab.id;
//   if (isVisible) {
//     chrome.sidePanel.setOptions({
//       tabId,
//       enabled: false
//     });
//     closeSidePanel(tabId);
//     isVisible = false
//   } else {
//     // @ts-ignore
//     chrome.sidePanel.open({ tabId,windowId });
//     isVisible = true
//   }
// });

